import type { FormInstance } from "ant-design-vue"
import type { RuleObject } from "ant-design-vue/es/form"

type UseFormStateOpts<FormState> = {
    getInitialState(): FormState
    rules?: {
        [k in keyof FormState]: IArrayable<RuleObject>
    }
}
export function useFormState<FormState extends Recordable>(opts: UseFormStateOpts<FormState>) {
    const { getInitialState, rules: _rules } = opts
    const formRef = ref<INullable<FormInstance>>(null)
    const formLoading = ref<boolean>(false)
    const formState = ref<FormState>(getInitialState())
    const rules = ref(_rules)
    async function handleFormSubmit(action: (formState: FormState) => IAwaitable<any>) {
        await formRef.value?.validate()
        await handleFormFinish(action)
    }
    function resetFormState() {
        formState.value = getInitialState()
        formLoading.value = false
    }
    async function handleFormFinish(action: (formState: FormState) => IAwaitable<any>) {
        try {
            formLoading.value = true
            await action(toValue(formState))
            formLoading.value = false
            resetFormState()
        } catch (error) {
            formLoading.value = false
            throw error
        }
    }
    function clearValidate() {
        if (formRef.value) {
            formRef.value.clearValidate()
        }
    }
    return {
        formRef,
        formState,
        rules,
        formLoading,
        handleFormSubmit,
        resetFormState,
        handleFormFinish,
        clearValidate
    }
}